package nc.impl.fa.asset.rule;

import java.util.ArrayList;
import java.util.Set;

import nc.bs.am.framework.action.ActionContext;
import nc.bs.am.framework.action.IRule;
import nc.impl.fa.asset.util.AccbookNextHandleQueryFactory;
import nc.impl.fa.asset.util.SendMessageToFipTool;
import nc.impl.fa.out.AssetToFipImpl;
import nc.itf.fa.service.INewTransactionService;
import nc.pub.fa.card.CardTabConst;
import nc.pub.fa.card.CardVOUtils;
import nc.pub.fa.common.manager.VOManager;
import nc.pubitf.org.IAccountingBookPubService;
import nc.vo.am.common.AbstractAggBill;
import nc.vo.am.common.BizContext;
import nc.vo.am.common.util.ArrayUtils;
import nc.vo.am.common.util.CloneUtil;
import nc.vo.am.common.util.CollectionUtils;
import nc.vo.am.manager.AccbookManager;
import nc.vo.am.proxy.AMProxy;
import nc.vo.am.pub.uap.ModuleInfoQuery;
import nc.vo.fa.asset.AssetVO;
import nc.vo.fa.assetcard.AggCardVO;
import nc.vo.fa.assetcard.CardhistoryVO;
import nc.vo.logging.Debug;
import nc.vo.org.AccountingBookVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.SuperVO;
import nc.vo.pub.lang.UFDate;

public class SendMessageToFipUpdateAfterRule<T extends AggCardVO> implements IRule<T> {
	public void process(ActionContext<T> context, T... aggVos) throws BusinessException {
		String pk_org = aggVos[0].getParentVO().getAttributeValue("pk_org").toString();
		Set pk_accbooks = AccbookManager.queryBookIDsByOrg((String) pk_org,
				(String) BizContext.getInstance().getBizDate().toString());
		ArrayList<T> aggVosFilter = new ArrayList<T>();
		for (T aggVo : aggVos) {
			String pk_accbook = aggVo.getChildren(nc.vo.fa.assetcard.CardhistoryVO.class)[0]
					.getAttributeValue("pk_accbook").toString();
			if (!pk_accbooks.contains(pk_accbook))
				continue;
			aggVosFilter.add(aggVo);
		}
		T[] aggVosNew = CollectionUtils.toArray(aggVosFilter);
		if (ModuleInfoQuery.isFIPEnabled() && ArrayUtils.isNotEmpty(aggVosNew)) {
			AssetToFipImpl fipSender = new AssetToFipImpl();
			AbstractAggBill[] billAddvo = SendMessageToFipTool.splitMutilBookData(aggVosNew);
			AggCardVO[] billOldVOs = this.queryOldVOs(aggVosNew);
			AbstractAggBill[] billDelvo = SendMessageToFipTool.splitMutilBookData((AbstractAggBill[]) billOldVOs);
			Object[] needAddVos = this.getFipMessageVOs(aggVosNew[0], billAddvo);
			Object[] needDelVos = this.getFipMessageDelVOs(aggVosNew[0], billDelvo);
			if (ArrayUtils.isNotEmpty((Object[]) needDelVos)) {
				fipSender.deleteFipMessage(null, (AbstractAggBill[]) needDelVos);
			}
			if (ArrayUtils.isNotEmpty((Object[]) needAddVos)) {
				fipSender.sendFipMessage(null, (AbstractAggBill[]) needAddVos);
			}
		}
	}

	private AbstractAggBill[] getFipMessageVOs(T aggVo, AbstractAggBill[] splitVOs) throws BusinessException {
		if (ArrayUtils.isEmpty((Object[]) splitVOs)) {
			return null;
		}
		String[] accbooks = CardVOUtils.getAllBooksFormAggvo(aggVo);
		ArrayList<String> eidtableBook = new ArrayList<String>();
		for (String pk_accbook : accbooks) {
			boolean isbookable = AccbookNextHandleQueryFactory.accbookEidtAble(aggVo, (String) pk_accbook);
			if (!isbookable)
				continue;
			eidtableBook.add(pk_accbook);
		}
		if (eidtableBook.size() == 0) {
			return null;
		}
		ArrayList<AbstractAggBill> fipMessageVOs = new ArrayList<AbstractAggBill>();
		for (AbstractAggBill aggBill : splitVOs) {
			String pk_accbook = CardVOUtils.getAllBooksFormAggvo((AggCardVO) ((AggCardVO) aggBill))[0];
			if (eidtableBook.contains(pk_accbook)) {
				fipMessageVOs.add(aggBill);
			}
			aggBill.setTableVO(CardTabConst.usufructasset_tab,
					(CircularlyAccessibleValueObject[]) aggVo.getTableVO(CardTabConst.usufructasset_tab));
		}
		return (AbstractAggBill[]) CollectionUtils.toArray(fipMessageVOs);
	}

	private AbstractAggBill[] getFipMessageDelVOs(T aggVo, AbstractAggBill[] splitVOs) throws BusinessException {
		if (ArrayUtils.isEmpty((Object[]) splitVOs)) {
			return null;
		}
		AssetVO assetVO = CardVOUtils.getAssetVOFormAggCardVO(aggVo);
		String pk_org = assetVO.getPk_org();
		UFDate business_date = assetVO.getBusiness_date();
		UFDate busiDate = business_date.asEnd();
		String[] accbooks = SendMessageToFipUpdateAfterRule.getAccountingBookID(busiDate, pk_org);
		ArrayList<String> eidtableBook = new ArrayList<String>();
		for (String pk_accbook : accbooks) {
			boolean isbookable = AccbookNextHandleQueryFactory.accbookEidtAble(aggVo, (String) pk_accbook);
			if (!isbookable)
				continue;
			eidtableBook.add(pk_accbook);
		}
		ArrayList<AbstractAggBill> endAccbookData = new ArrayList<AbstractAggBill>();
		AggCardVO aggCardVO = (AggCardVO) splitVOs[0];
		for (String tPk_accbook : eidtableBook) {
			AbstractAggBill newaggBill = (AbstractAggBill) CloneUtil.clone((Object) aggCardVO);
			AggCardVO newaggCardVO = (AggCardVO) newaggBill;
			CardhistoryVO[] newhistVOs = (CardhistoryVO[]) newaggCardVO.getChildren(CardhistoryVO.class);
			VOManager.setAttributeValue((SuperVO[]) newhistVOs, (String) "pk_accbook", (Object) tPk_accbook);
			endAccbookData.add(newaggBill);
		}
		if (eidtableBook.size() == 0) {
			return null;
		}
		return (AbstractAggBill[]) CollectionUtils.toArray(endAccbookData);
	}

	public static String[] getAccountingBookID(UFDate date, String... pk_financeorgs) {
		ArrayList<String> accountingBookPKsByAllOrgs = new ArrayList<String>();
		try {
			for (String pk_financeorg : pk_financeorgs) {
				AccountingBookVO[] bookVOs = ((IAccountingBookPubService) AMProxy
						.lookup(IAccountingBookPubService.class))
								.queryAccountingBookByFinanceOrgIDAndDate(pk_financeorg, date);
				if (!ArrayUtils.isNotEmpty((Object[]) bookVOs))
					continue;
				for (AccountingBookVO bookVO : bookVOs) {
					String pk_accountingbook = bookVO.getPk_accountingbook();
					accountingBookPKsByAllOrgs.add(pk_accountingbook);
				}
			}
		} catch (BusinessException e) {
			Debug.error((Object) e.getMessage());
		}
		return accountingBookPKsByAllOrgs.toArray(new String[0]);
	}
	

	
	private AggCardVO[] queryOldVOs(T... aggVos) throws BusinessException {
		return ((INewTransactionService) AMProxy.lookup(INewTransactionService.class)).queryOldVOs_RequiresNew(aggVos);
	}
}
